/* 
 * SIT, Sistema Integral de Tramites del Ministerio de Minas y Energia
 * Copyright 2010, como se indica en  los tags @author. Revise
 * el archivo  copyright.txt en la lista de desarrollo 
 * 
 * Este NO es un software libre y no puede ser redistribuido y/o modificado
 * bajo ningun termino. El codigo es propietario y solo  puede
 * ser utilizado bajo permiso explicito del Ministerio de Minas y Energia
 * 
 * Este Software no es distribuido publicamente y solo deberia estar
 * ejecutandose en el entorno de desarrollo del Ministerio de Minas y Energia,
 * si por alguna razon este codigo se ejecuta en un entorno diferente estaria 
 * violando la ley de derechos de autor que lo proteje., Al igual que cualquier 
 * uso  del codigo o cualquiera de los componentes del sistema
 * sin autorizacion explicita de los autores.
 * 
 * Si necesita autorizacion para la utilizacion del codigo o parte de el 
 * por favor refierase a la lista de desarrollo del proyecto para contactar 
 * al autor indicado en el tag @author, o comuniquese con 
 * el grupo de arquitectura de software del proyecto.
 */
package co.edu.udistrital.database.dao.impl;

import java.io.Serializable;

import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import co.edu.udistrital.database.dao.api.ICrud;
import co.edu.udistrital.database.exceptions.CrudException;

/**
 * Servicio para operaciones de CRUD. Provee las operaciones basicas: creacion,
 * modificacion, eliminacion. <br>
 * 
 * @author <a href="mailto:rcabezas1@gmail.com">Edwin Romero</a>
 * @version $1.0
 */
@Repository
@Transactional
public class CrudImpl<T> implements ICrud<T> {
	
	private static org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(CrudImpl.class);
	
	/** Manejador de Entidades. */
	@PersistenceContext
	private transient EntityManager entityManager;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * co.edu.udistrital.database.dao.api.ICrud#save(co.edu.udistrital.database.entities.GenericTable
	 * )
	 */
	@Override
//	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)//cambia REQUIRES_NEW para que no cree transacciones nuevas y se omite por que son valores por defecto.
	public final Class<T> save(Class<T> entity) throws CrudException {
		try {
            LOG.debug("...persistiendo objeto : " + entity);
            Class<T> o =  entityManager.merge(entity);
			return o;
		} catch (Exception e) {
			throw new CrudException(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see co.edu.udistrital.database.dao.api.ICrud#delete(java.lang.Class<T>,
	 * java.io.Serializable)
	 */
	@Override
//	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)//cambia REQUIRES_NEW para que no cree transacciones nuevas y se omite por que son valores por defecto.
	public void delete(Serializable id) throws CrudException {
		try {
			/* no funciona correctamente */
			//Object table = entityManager.getReference(entityType, id);
			Object table = entityManager.find(this.getClass(), id);
			if(table == null){
				throw new EntityNotFoundException("No existe El objeto " + this.getClass() + "con Id=" + id);
			}
			LOG.info("...eliminando objeto de tipo: " + this.getClass() + " , ID:" + id);
			entityManager.remove(table);
		} catch (Exception e) {
			e.printStackTrace();
			throw new CrudException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * co.edu.udistrital.database.dao.api.ICrud#refresh(co.edu.udistrital.database.entities.GenericTable
	 * )
	 */
	@Override
//	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)//cambia REQUIRES_NEW para que no cree transacciones nuevas y se omite por que son valores por defecto.
	public final Class<T> refresh(Class<T> entity) throws CrudException {
		try {
			LOG.debug("...recargando objeto : " + entity );
			entityManager.refresh(entity); 
			
			return entity;
		} catch (Exception e) {
			throw new CrudException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * co.edu.udistrital.database.dao.api.ICrud#flush( )
	 */
	@Override
	public void flush() throws CrudException{
		try {
			LOG.debug("flushing session.....");
			entityManager.flush();
		} catch (Exception e) {
			LOG.error(" FALLA flushing session.....", e);
			throw new CrudException(e);
		}
	}
	
	

}
